package controllers;

import play.*;
import play.data.validation.*;
import play.db.jpa.Blob;
import play.libs.Images;
import play.libs.MimeTypes;
import play.mvc.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.*;

import javax.persistence.Lob;

import net.sf.oval.constraint.Size;

import models.*;

public class Events extends Controller {

	/**
	 * Detail view for an event
	 * @param id
	 */
	public static void show(long id) {
		User user = Security.getConnected();
		Event event = Event.findById(id);
		notFoundIfNull(event);
		render(user, event);
	}
	
	public static void create() {
		User user = Security.getConnected();
		
		EventCategory[] categories = EventCategory.values();
		
		if (user != null)
			render(user, categories);
		else
			Application.index(null, null, null);
	}
	
	/**
	 * set an event active
	 * @param id
	 */
	public static void activate(long id) {
		User user = Security.getConnected();
		if (user instanceof models.Admin) {
			Event event = Event.findById(id);
			event.isActive = true;
			event.save();
			show(id);
		} else
			Application.index(null, null, null);
	}
	
	public static void showPicture(long id) {
		Event event = Event.findById(id);
		notFoundIfNull(event);
		response.setContentTypeIfNotSet(event.picture.type());
		java.io.InputStream picture = event.picture.get();
		if (picture != null)
			renderBinary(picture);
		else
			renderBinary(new File("public/images/eventPicture.jpg"));
	}
	
	public static void createEvent(
			@Required
			String name,

			String description,
				
			@Required
			@MinSize(10)
			@MaxSize(10)
			String startDateString,
				
			@MinSize(10)
			@MaxSize(10)
			String endDateString,

			@Required
			String city,
			
			//range?
			int zipcode,
			
			File photo,
			
			String street,
				
			int streetNumber,
				
			@Required
			EventCategory category
			) throws FileNotFoundException {
			
			User user = Security.getConnected();
			
			if (user != null) {
				
				int[] yearMonthDayStart = Tools.splitDate(startDateString);
				Date startDate = new GregorianCalendar(yearMonthDayStart[0], yearMonthDayStart[1]-1, yearMonthDayStart[2]).getTime();
				
		    	if (validation.hasErrors() || Event.isEventExistent(name, startDate) || startDate.getTime() < new Date().getTime()) {
		    		if (Event.isEventExistent(name, startDate))
		        		flash.put("existentError", "Sorry, but this event seems to be in the database already.");
		    		
		    		if (startDate.getTime() < new Date().getTime())
		    			flash.put("startDateError", "Sorry, but your start date must be in the future.");
		    		
		            validation.keep();
		            params.flash();
		            flash.error("Please correct these errors !");
		            create();
		        }
		    	
		    	Event newEvent = new Event(name, startDate, city, category);
		    	newEvent.description = description;
		    	
		    	if (endDateString.length() == 10 ) {
		    		int[] yearMonthDayEnd = Tools.splitDate(endDateString);
		    		newEvent.endDate = new GregorianCalendar(yearMonthDayEnd[0], yearMonthDayEnd[1]-1, yearMonthDayEnd[2]).getTime();
		    	} else
		    		newEvent.endDate = startDate;
		    	
		    	newEvent.zipcode = zipcode;
		    	newEvent.street = street;
		    	newEvent.streetNumber = streetNumber;
		    	
		    	if (photo != null && photo.exists()) {
		    		newEvent.picture = new Blob();
		    		newEvent.picture.set(new FileInputStream(photo), MimeTypes.getContentType(photo.getName()));
		    	}
		    	newEvent.save();
		    	
		    	show(newEvent.id);
			} else
				Application.index(null, null, null);
	}
	
	public static void edit(long id) {
		User user = Security.getConnected();
		
		if (!(user instanceof models.Admin))
			Application.index(null, null, null);
		
		EventCategory[] categories = EventCategory.values();
		Event event = Event.findById(id);
		
		flash.put("eventId", event.id);
		
		notFoundIfNull(event);
		render(user, event, categories);
	}
	
	public static void save (
		long id,
		
		@Required
		String name,

		String description,
				
		@Required
		@MinSize(10)
		@MaxSize(10)
		String startDateString,
				
		@MinSize(10)
		@MaxSize(10)
		String endDateString,

		@Required
		String city,
			
		//range?
		int zipcode,
			
		File photo,
			
		String street,
				
		int streetNumber,
				
		@Required
		EventCategory category
		) throws FileNotFoundException {
			
			User user = Security.getConnected();
			
			if (user instanceof models.Admin) {
				
				Event event = Event.findById(id);
				
				int[] yearMonthDayStart = Tools.splitDate(startDateString);
				Date startDate = new GregorianCalendar(yearMonthDayStart[0], yearMonthDayStart[1]-1, yearMonthDayStart[2]).getTime();
				
		    	if (validation.hasErrors() || event == null || startDate.getTime() < new Date().getTime()) {
		    		
		    		if (event == null)
		    			flash.put("eventExistentError", "Sorry, but the event cannot be found in our database");
		    		
		    		if (startDate.getTime() < new Date().getTime())
		    			flash.put("startDateError", "Sorry, but your start date must be in the future.");
		    		
		            validation.keep();
		            params.flash();
		            flash.error("Please correct these errors !");
		            create();
		        }
		    	
		    	event.description = description;
		    	
		    	if (endDateString.length() == 10 ) {
		    		int[] yearMonthDayEnd = Tools.splitDate(endDateString);
		    		event.endDate = new GregorianCalendar(yearMonthDayEnd[0], yearMonthDayEnd[1]-1, yearMonthDayEnd[2]).getTime();
		    	} else
		    		event.endDate = startDate;
		    	
		    	event.zipcode = zipcode;
		    	event.street = street;
		    	event.streetNumber = streetNumber;
		    	
		    	if (photo != null) {
		    		event.picture = new Blob();
		    		event.picture.set(new FileInputStream(photo), MimeTypes.getContentType(photo.getName()));
		    	}
		    	
		    	event.save();
		    	
		    	show(event.id);
			} else
				Application.index(null, null, null);
	}
}
